package org.my.spring.agent.app.config;

import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.MessageChatMemoryAdvisor;
import org.springframework.ai.chat.memory.ChatMemory;
import org.springframework.ai.chat.memory.InMemoryChatMemoryRepository;
import org.springframework.ai.chat.memory.MessageWindowChatMemory;
import org.springframework.ai.deepseek.DeepSeekChatModel;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * 智能代理配置类
 *
 * <p>负责配置 Spring AI 相关的核心组件，包括聊天内存管理和聊天客户端。</p>
 *
 * <p>主要功能:</p>
 * <ul>
 *   <li>配置聊天内存管理，用于存储对话历史</li>
 *   <li>创建聊天客户端实例，集成 DeepSeek 模型</li>
 *   <li>设置聊天记忆顾问，自动管理对话上下文</li>
 * </ul>
 */
@Configuration
public class AgentConfig {

    /**
     * 配置聊天内存管理器
     *
     * <p>创建一个基于内存的消息窗口聊天内存，用于存储和管理对话历史。</p>
     *
     * <p>配置参数:</p>
     * <ul>
     *   <li><b>maxMessages</b>: 最大保存消息数(100条)，控制内存使用量</li>
     *   <li><b>chatMemoryRepository</b>: 使用内存存储实现，适合开发环境</li>
     * </ul>
     *
     * <p>生产环境建议替换为持久化存储实现</p>
     *
     * @return ChatMemory 聊天内存实例
     */
    @Bean
    public ChatMemory chatMemory() {
        return MessageWindowChatMemory.builder()
                .maxMessages(100)  // 设置最大保存100条消息
                .chatMemoryRepository(new InMemoryChatMemoryRepository())  // 使用内存存储
                .build();
    }

    /**
     * 配置聊天客户端
     *
     * <p>创建并配置 ChatClient 实例，集成 DeepSeek 模型和聊天内存管理。</p>
     *
     * <p>关键配置:</p>
     * <ul>
     *   <li>集成 DeepSeek 模型作为底层语言模型</li>
     *   <li>添加消息聊天记忆顾问，自动维护对话上下文</li>
     *   <li>关联聊天内存管理器，实现对话历史记录</li>
     * </ul>
     *
     * @param model DeepSeekChatModel 实例，由 Spring 自动注入
     * @return 配置完成的 ChatClient 实例
     */
    @Bean
    public ChatClient chatClient(DeepSeekChatModel model) {
        return ChatClient.builder(model)  // 使用 DeepSeek 模型作为基础
                .defaultAdvisors(
                        // 添加消息聊天记忆顾问，关联聊天内存
                        MessageChatMemoryAdvisor.builder(chatMemory()).build()
                )
                .build();
    }
}
